#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btn_pdf_clicked()
{

    // 字体文件路径
    const auto font_file_path = "../../res/SIMKAI.TTF";
    ui->textEdit_output->append(QString("font_file_path : %1").arg(font_file_path));
    // 读取字体中所有文字
    const std::set<std::string> char_set = get_char_vector_from_ttf(font_file_path);
    // 按照每行15个，每页300个写入pdf
    ui->textEdit_output->append("start generate pdf...");
    generate_pdf_file(char_set, font_file_path, "SIMKAI.pdf");
    ui->textEdit_output->append("generate done!!!\n");
}

void MainWindow::generate_pdf_file(const std::set<std::string> &char_set, const char *ttf_file_path, const char *output_file_path) {
    const HPDF_Doc pdf = HPDF_New(nullptr, nullptr);
    HPDF_SetCompressionMode(pdf, HPDF_COMP_ALL);
    // 使用utf编码
    HPDF_UseUTFEncodings(pdf);
    // 使用utf-8加载字符文件
    const auto font_name = HPDF_LoadTTFontFromFile(pdf, ttf_file_path, HPDF_TRUE);
    const HPDF_Font font = HPDF_GetFont(pdf, font_name, "UTF-8");
    if (font == nullptr) {
        ui->textEdit_output->append("读取字体文件失败\n");
        HPDF_Free(pdf);
        return;
    }

    std::vector char_list(char_set.begin(), char_set.end());
    for (auto page_iter = char_list.begin(); page_iter < char_list.end(); page_iter += 300) {
        // 300个字符为一页
        const auto page_end_iter = page_iter + 300 < char_list.end() ? page_iter + 300 : char_list.end();
        std::vector words(page_iter, page_end_iter);

        const HPDF_Page page = HPDF_AddPage(pdf);
        const auto page_height = HPDF_Page_GetHeight(page);
        const HPDF_REAL font_size = page_height / 25;
        HPDF_REAL y = page_height - font_size;
        HPDF_Page_SetFontAndSize(page, font, font_size);
        HPDF_Page_BeginText(page);
        for (auto row_iter = words.begin(); row_iter < words.end(); row_iter += 15) {
            // 15个字符为一行
            const auto row_end_item = row_iter + 15 < words.end() ? row_iter + 15 : words.end();
            auto text = std::accumulate(row_iter, row_end_item, std::string{},
                                        [](const std::string &a, const std::string &b) {
                                            return a + b;
                                        });
            // 写入pdf
            HPDF_Page_TextOut(page, 0, y, text.c_str());
            y -= font_size;
        }
        HPDF_Page_EndText(page);
    }
    if (HPDF_SaveToFile(pdf, output_file_path) != HPDF_OK) {
        ui->textEdit_output->append("pdf文件保存失败\n");
    }
    HPDF_Free(pdf);
}

std::set<std::string> MainWindow::get_char_vector_from_ttf(const char *ttf_file_path) {
    FT_Library library;
    FT_Face face;
    FT_Init_FreeType(&library);
    FT_New_Face(library, ttf_file_path, 0, &face);
    FT_UInt flag;
    FT_ULong char_code = FT_Get_First_Char(face, &flag);
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
    std::set<std::string> words;
    // 遍历字符文件中包含的unicode
    while (flag != 0) {
        // 将Unicode转为对应字符
        auto word = converter.to_bytes(char_code);
        words.insert(word);
        char_code = FT_Get_Next_Char(face, char_code, &flag);
    }
    FT_Done_Face(face);
    FT_Done_FreeType(library);
    return words;
}

